<?php

namespace app\admin\controller;

use Dcat\EasyExcel\Excel;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use service\exception\ServiceException;
use service\vo\subject\SubjectExt;
use service\vo\subject\SubjectExtBind;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\response\Json;

class Subject extends Base
{
    public function initialize()
    {
        parent::initialize();
    }

    /**
     * 搜索题目
     */
    public function search_subject(): Json
    {
        try {
            //接收传递过来的条件参数
            //语向
            $lanDir = request()->get('lanDir') ?? "";
            //Rate
            $rate    = request()->get('rate') ?? "";
            //领域id，1.公司法，可参考配置文件
            $territoryId    = request()->get('territoryId') ?? "";
            //原文
            $sourceText = request()->get('sourceText') ?? "";
            //开始时间
            $startTime = request()->get('startTime') ?? "";
            //结束时间
            $endTime = request()->get('endTime') ?? "";

            //过滤条件
            $filterCriteria = [];
            if (!empty($lanDir)) {
                $filterCriteria['LanDir'] = $lanDir;
            }
            if (!empty($rate)) {
                $filterCriteria['Rate'] = $rate;
            }
            if (!empty($territoryId)) {
                $filterCriteria['TerritoryId'] = $territoryId;
            }
            if ($sourceText != "") {
                $filterCriteria['SourceText'] = $sourceText;
            }
            if (!empty($startTime) || !empty($endTime)) {
                $filterCriteria['AddTime'] = ['start' => $startTime, 'end' => $endTime];
            }

            //排序条件
            $sorterCriteria = ['ID' => false];

            $dataList = $this->getSubjectService()->searchSubjects($this->page, $this->pageSize, $filterCriteria, $sorterCriteria);
            $dataArr = $dataList->getData();
            $dataCount = $dataList->getCount();

            $data = [];
            $territoryConfig = config('ext.territory');
            $rateConfig = config('ext.subjectRate');
            if (!empty($dataArr)) {
                foreach ($dataArr as $val) {
                    $data[] = [
                        'id' => $val->getId(),
                        'lanDir'    =>   $val->getLanDir(),
                        'rate'       =>   $val->getRate(),
                        'rateName'       =>   $rateConfig[$val->getRate()]['name'],
                        'territoryId' =>   $val->getTerritoryId(),
                        'territoryName' =>   $territoryConfig[$val->getTerritoryId()]['name'],
                        'sourceText' =>   htmlspecialchars_decode($val->getSourceText()),
                        'translationText'   =>   htmlspecialchars_decode($val->getTranslationText()),
                        'from'   =>   $val->getFrom(),
                        'userId'   =>   $val->getUserId(),
                        'userType'   =>   $val->getUserType(),
                        'addTime' => $val->getAddTime()
                    ];
                }
            }
            $resultData = [
                "total" => $dataCount,
                "records" => $data
            ];
            return $this->requestSuccessReturn($resultData);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 添加题目
     */
    public function add_subject(): Json
    {
        try {
            //语向
            $lanDir = request()->post('lanDir');
            //难度系数
            $rate    = request()->post('rate');
            //领域id
            $territoryId = request()->post('territoryId');
            //原文
            $sourceText = request()->post('sourceText');
            //译文
            $translationText = request()->post('translationText');
            //来源
            $from = request()->post('from');
            //密码
            if (empty($lanDir)) {
                throw new Exception("语向必传");
            }
            if (empty($rate)) {
                throw new Exception("难度系数必传");
            }
            if (empty($territoryId)) {
                throw new Exception("领域必传");
            }
            if (empty($sourceText)) {
                throw new Exception("原文必传");
            }
            if (empty($translationText)) {
                throw new Exception("译文必传");
            }


            $vo = new \service\vo\subject\Subject();
            $vo->setLanDir($lanDir);
            $vo->setRate($rate);
            $vo->setTerritoryId($territoryId);
            $vo->setSourceText(htmlspecialchars($sourceText));
            $vo->setTranslationText(htmlspecialchars($translationText));
            $vo->setFrom($from);
            $vo->setUserId(request()->user['id']);
            $vo->setUserType(1);

            $id = $this->getSubjectService()->addSubject($vo);
            $data = ['id' => $id];
            return $this->requestSuccessReturn($data);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 编辑题目
     */
    public function edit_subject(): Json
    {
        try {
            //id
            $id = request()->put('id');
            //语向
            $lanDir = request()->put('lanDir');
            //难度系数
            $rate    = request()->put('rate');
            //领域id
            $territoryId = request()->put('territoryId');
            //原文
            $sourceText = request()->put('sourceText');
            //译文
            $translationText = request()->put('translationText');
            //来源
            $from = request()->put('from');
            if (empty($lanDir)) {
                throw new Exception("语向必传");
            }
            if (empty($rate)) {
                throw new Exception("难度系数必传");
            }
            if (empty($territoryId)) {
                throw new Exception("领域必传");
            }
            if (empty($sourceText)) {
                throw new Exception("原文必传");
            }
            if (empty($translationText)) {
                throw new Exception("译文必传");
            }


            $vo = new \service\vo\subject\Subject();
            $vo->setId($id);
            $vo->setLanDir($lanDir);
            $vo->setRate($rate);
            $vo->setTerritoryId($territoryId);
            $vo->setSourceText(htmlspecialchars($sourceText));
            $vo->setTranslationText(htmlspecialchars($translationText));
            $vo->setFrom($from);

            $id = $this->getSubjectService()->editSubject($vo);
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //获取题目
    public function get_subject(): Json
    {
        try {
            //id
            $id = request()->get('id');

            if (empty($id)) {
                throw new Exception("id必传");
            }

            $vo = $this->getSubjectService()->getSubjectById($id);
            $rateConfig = config('ext.subjectRate');
            $territoryConfig = config('ext.territory');
            $data = [
                'id' => $vo->getId(),
                'lanDir'    =>   $vo->getLanDir(),
                'lanDirName'    =>   $vo->getLanDir() == 'EC' ? '英译中' : '中译英',
                'rate'       =>   $vo->getRate(),
                'rateName'       =>   $rateConfig[$vo->getRate()]['name'],
                'territoryId' =>   $vo->getTerritoryId(),
                'territoryName' =>   $territoryConfig[$vo->getTerritoryId()]['name'],
                'sourceText' =>   htmlspecialchars_decode($vo->getSourceText()),
                'translationText'   =>   htmlspecialchars_decode($vo->getTranslationText()),
                'from'   =>   $vo->getFrom(),
                'userId'   =>   $vo->getUserId(),
                'userType'   =>   $vo->getUserType(),
                'addTime' => $vo->getAddTime()
            ];
            return $this->requestSuccessReturn($data);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //导入题目
    public function analysis_import_subject() : Json
    {
        try {
            // 直接读取前端上传的文件
            // 创建读操作
            $reader = IOFactory::createReader('Xlsx');
            // 打开文件 载入excel表格
            $spreadsheet = $reader->load($_FILES['file']['tmp_name']);
            // 获取活动工作簿
            $sheet = $spreadsheet->getActiveSheet();
            // 获取内容的最大行 如 4
            $row = $sheet->getHighestRow();
            //将表格转换为数组
            $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
            //读取数据
            if(empty($sheetData)){
                throw new \think\Exception("读取文件失败");
            }
            //获取领域配置
            $territoryConfig = config('ext.territory');
            $territoryData = [];
            foreach ($territoryConfig as $k => $v) {
                $territoryData[$v['name']] = $v['id'];
            }
            //题目扩展配置
            $subjectExtConfig = config('ext.subjectExt');
            //难度系数配置
            $subjectRateConfig = config('ext.subjectRate');
            //数据集
            $dataList = [];
            for ($i=2; $i<=$row; $i++){
                $columns = $sheetData[$i];
                if(is_array($columns)){
                    if(empty($columns['A']) || empty($columns['B']) || empty($columns['C']) || empty($columns['D']) || empty($columns['E'])){
                        break;
                    }
                    $data = [];
                    foreach ($columns as $key => $column){
                        if($key == 'A'){
                            //语向
                            $data['lanDir'] = $column;
                        }else if($key == 'B'){
                            //难度系数
                            $data['rate'] = $column;
                            $data['rateName'] = $subjectRateConfig[$column]['name'];
                        }else if($key == 'C'){
                            //细分领域
                            $data['territoryId'] = $territoryData[$column];
                            $data['territoryName'] = $column;
                        }else if($key == 'D'){
                            //原文
                            $data['sourceText'] = $column;
                        }else if($key == 'E'){
                            $data['translationText'] = $column;
                        }else if($key == 'F'){
                            $data['from'] = $column;
                        }
                    }
                    //背景知识
                    $ext1 = $this->getImportExt1($columns);
                    //翻译技巧
                    $ext2 = $this->getImportExt2($columns);
                    //重点词汇
                    $ext3 = $this->getImportExt3($columns);
                    $data['ext'] = [
                        [
                            'id' => $subjectExtConfig['1']['id'],
                            'name' => $subjectExtConfig['1']['name'],
                            'list' => $ext1,
                        ],
                        [
                            'id' => $subjectExtConfig['2']['id'],
                            'name' => $subjectExtConfig['2']['name'],
                            'list' => $ext2,
                        ],
                        [
                            'id' => $subjectExtConfig['3']['id'],
                            'name' => $subjectExtConfig['3']['name'],
                            'list' => $ext3,
                        ]
                    ];
                    $dataList[] = $data;
                }
            }
            //导入数据
            $this->importSubject($dataList);
            return $this->requestSuccessReturn($dataList);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //获取题目已绑定的扩展
    public function get_subject_bind_ext() : Json
    {
        try {
            //id
            $id = request()->get('id');

            if (empty($id)) {
                throw new Exception("id必传");
            }

            //获取题目下所有的扩展
            $voArr = $this->getSubjectService()->getSubjectExtBindsBySubjectId($id);
            $data = [];
            //扩展id集合
            $extIds = [];
            if(!empty($voArr)){
                foreach ($voArr as $vo){
                    $extIds[] = $vo->getSubjectExtId();
                }

                //获取扩展信息
                $extObj = [];
                $extArr = $this->getSubjectService()->getSubjectExtByIds($extIds);
                foreach ($extArr as $ext){
                    $extObj[$ext->getId()] = $ext;
                }

                $extConfig = config('ext.subjectExt');
                foreach ($voArr as $vo){
                    $data[] = [
                        'id' => $vo->getId(),
                        'subjectId' => $vo->getSubjectId(),
                        'subjectExtId' => $vo->getSubjectExtId(),
                        'subjectExtType' => $extObj[$vo->getSubjectExtId()]->getType(),
                        'subjectExtTypeName' => $extConfig[$extObj[$vo->getSubjectExtId()]->getType()]['name'],
                        'subjectExtTitle'    =>  $extObj[$vo->getSubjectExtId()]->getTitle(),
                        'subjectExtContent' => htmlspecialchars_decode($extObj[$vo->getSubjectExtId()]->getContent()),
                        'subjectExtBindType' => $vo->getType(),
                    ];
                }
            }
            return $this->requestSuccessReturn($data);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //绑定扩展
    public function bind_subject_ext() : Json
    {
        try {
            //题目id
            $subjectId = request()->post('subjectId');
            //题目扩展id集合
            $subjectExtIds = request()->post('subjectExtIds');
            if (empty($subjectId)) {
                throw new Exception("题目id必传");
            }
            if (empty($subjectExtIds)) {
                throw new Exception("扩展id集合必传");
            }

            $subjectExtIdArr = explode(',', $subjectExtIds);
            $arr = [];
            foreach ($subjectExtIdArr as $subjectExtId){
                $vo = new SubjectExtBind();
                $vo->setSubjectExtId($subjectExtId);
                $vo->setSubjectId($subjectId);
                $arr[] = $vo;
            }
            $res = $this->getSubjectService()->addSubjectExtBinds($arr);
            if(empty($res)){
                throw new \think\Exception("绑定失败");
            }
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //解绑扩展
    public function delete_subject_ext_bind() : Json
    {
        try {
            //id
            $id = request()->delete('id');

            if (empty($id)) {
                throw new Exception("id必传");
            }

            $result = $this->getSubjectService()->deleteSubjectExtBindById($id);
            if ($result == 0) {
                throw new Exception("删除失败");
            }

            //同时删除题目扩展绑定
            $this->getSubjectService()->deleteSubjectExtBindByExtId($id);
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 搜索题目扩展
     */
    public function search_subject_ext(): Json
    {
        try {
            //接收传递过来的条件参数
            //语向
            $type = request()->get('type') ?? "";
            $title = request()->get('title') ?? "";
            $noIds = request()->get('noIds') ?? "";

            //过滤条件
            $filterCriteria = [];
            if (!empty($type)) {
                $filterCriteria['Type'] = $type;
            }
            if (!empty($title)) {
                $filterCriteria['Title'] = $title;
            }
            if (!empty($noIds)) {
                $filterCriteria['NotIdIn'] = explode(",", $noIds);
            }

            //排序条件
            $sorterCriteria = ['ID' => false];

            $dataList = $this->getSubjectService()->searchSubjectExt($this->page, $this->pageSize, $filterCriteria, $sorterCriteria);
            $dataArr = $dataList->getData();
            $dataCount = $dataList->getCount();

            $data = [];
            $extConfig = config('ext.subjectExt');
            if (!empty($dataArr)) {
                foreach ($dataArr as $val) {
                    $data[] = [
                        'id' => $val->getId(),
                        'type'    =>   $val->getType(),
                        'typeName'  =>  $extConfig[$val->getType()]['name'] ?? '',
                        'title' =>  $val->getTitle(),
                        'content'   =>   htmlspecialchars_decode($val->getContent()),
                        'addTime' => $val->getAddTime()
                    ];
                }
            }
            $resultData = [
                "total" => $dataCount,
                "records" => $data
            ];
            return $this->requestSuccessReturn($resultData);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 添加题目扩展
     */
    public function add_subject_ext(): Json
    {
        try {
            //类型
            $type = request()->post('type');
            //名称
            $title    = request()->post('title');
            //内容
            $content    = request()->post('content');
            if (empty($type)) {
                throw new Exception("类型必传");
            }
            if (empty($title)) {
                throw new Exception("名称必传");
            }
            if (empty($content)) {
                throw new Exception("内容必传");
            }

            $vo = new SubjectExt();
            $vo->setType($type);
            $vo->setTitle($title);
            $vo->setContent(htmlspecialchars($content));
            $id = $this->getSubjectService()->addSubjectExt($vo);
            $data = ['id' => $id];
            return $this->requestSuccessReturn($data);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 编辑题目扩展
     */
    public function edit_subject_ext(): Json
    {
        try {
            //id
            $id = request()->put('id');
            //类型
            $type = request()->put('type');
            //名称
            $title    = request()->put('title');
            //内容
            $content    = request()->put('content');
            if (empty($type)) {
                throw new Exception("类型必传");
            }
            if (empty($title)) {
                throw new Exception("名称必传");
            }
            if (empty($content)) {
                throw new Exception("内容必传");
            }


            $vo = new SubjectExt();
            $vo->setId($id);
            $vo->setType($type);
            $vo->setTitle($title);
            $vo->setContent(htmlspecialchars($content));

            $id = $this->getSubjectService()->editSubjectExt($vo);
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //获取题目扩展
    public function get_subject_ext(): Json
    {
        try {
            //id
            $id = request()->get('id');

            if (empty($id)) {
                throw new Exception("id必传");
            }

            $vo = $this->getSubjectService()->getSubjectExtById($id);
            $data = [
                'id' => $vo->getId(),
                'type'    =>   $vo->getType(),
                'title'    =>  $vo->getTitle(),
                'content'   =>   htmlspecialchars_decode($vo->getContent()),
                'addTime' => $vo->getAddTime()
            ];
            return $this->requestSuccessReturn($data);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //删除题目扩展
    public function delete_subject_ext(): Json
    {
        try {
            //id
            $id = request()->delete('id');

            if (empty($id)) {
                throw new Exception("id必传");
            }

            $result = $this->getSubjectService()->deleteSubjectExtById($id);
            if ($result == 0) {
                throw new Exception("删除失败");
            }

            //同时删除题目扩展绑定
            $this->getSubjectService()->deleteSubjectExtBindByExtId($id);
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //更新题目扩展另见状态
    public function update_subject_ext_bind_type() : Json
    {
        try {
            //id
            $id = request()->put('id');
            //类型
            $type = request()->put('type');

            if (empty($id)) {
                throw new Exception("id必传");
            }
            if (!in_array($type, [0, 1])) {
                throw new Exception("类型必传");
            }

            $res = $this->getSubjectService()->setSubjectExtBindTypeById($id, $type);
            if(empty($res)){
                throw new Exception("更新失败");
            }
            return $this->requestSuccessReturn([]);
        } catch (Exception $e) {
            return $this->requestFailReturn($e->getMessage(), $e->getCode());
        }
    }

    //读取导入数据的背景知识
    private function getImportExt1(array $columns): array
    {
        $ext = [];
        if(!empty($columns['G'])){
            $ext[] = [
                'type'  => 1,
                'title' => $columns['G'],
                'content' => '',
            ];
        }
        if(!empty($columns['H'])){
            $ext[] = [
                'type'  => 1,
                'title' => $columns['H'],
                'content' => '',
            ];
        }
        if(!empty($columns['I'])){
            $ext[] = [
                'type'  => 1,
                'title' => $columns['I'],
                'content' => '',
            ];
        }
        return $ext;
    }

    //读取导入数据的翻译技巧
    private function getImportExt2(array $columns): array
    {
        $ext = [];
        if(!empty($columns['J'])){
            $ext[] = [
                'type'  => 2,
                'title' => $columns['J'],
                'content' => '',
            ];
        }
        if(!empty($columns['K'])){
            $ext[] = [
                'type'  => 2,
                'title' => $columns['K'],
                'content' => '',
            ];
        }
        if(!empty($columns['L'])){
            $ext[] = [
                'type'  => 2,
                'title' => $columns['L'],
                'content' => '',
            ];
        }
        return $ext;
    }

    //读取导入数据的重点词汇
    private function getImportExt3(array $columns): array
    {
        $ext = [];
        if(!empty($columns['M'])){
            $ext[] = [
                'type'  => 3,
                'title' => $columns['M'],
                'content' => '',
            ];
        }
        if(!empty($columns['N'])){
            $ext[] = [
                'type'  => 3,
                'title' => $columns['N'],
                'content' => '',
            ];
        }
        if(!empty($columns['O'])){
            $ext[] = [
                'type'  => 3,
                'title' => $columns['O'],
                'content' => '',
            ];
        }
        return $ext;
    }

    //导入题目

    /**
     * @throws ServiceException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    private function importSubject(array $data) : void
    {
        foreach ($data as $column => $value) {
            //整理题目
            $subject = new \service\vo\subject\Subject();
            $subject->setUserId(request()->user['id']);
            $subject->setFrom($value['from']);
            $subject->setRate($value['rate']);
            $subject->setUserType(1);
            $subject->setLanDir($value['lanDir']);
            $subject->setSourceText($value['sourceText']);
            $subject->setTerritoryId($value['territoryId']);
            $subject->setTranslationText($value['translationText']);

            //题目扩展
            $ext = $value['ext'];
            //题目扩展集合
            $extList = [];
            if(!empty($ext) && is_array($ext)){
                foreach ($ext as $extItem) {
                    if(!empty($extItem['list'])){
                        $extList = array_merge($extList, $extItem['list']);
                    }
                }
            }

            //添加题目扩展数据
            $extIds = [];
            if(!empty($extList)){
                foreach ($extList as $extItem) {
                    //先查询扩展
                    $extVo = $this->getSubjectService()->getSubjectExtByTitle($extItem['title']);
                    if(!empty($extVo)){
                        $extIds[] = $extVo->getId();
                    }else{
                        $ext = new \service\vo\subject\SubjectExt();
                        $ext->setTitle($extItem['title']);
                        $ext->setContent($extItem['content']);
                        $ext->setType($extItem['type']);
                        $extIds[] = $this->getSubjectService()->addSubjectExt($ext);
                    }
                }
            }
            //添加题目
            $subjectId = $this->getSubjectService()->addSubject($subject);

            //绑定数据
            if(!empty($subjectId) && !empty($extIds)){
                $this->getSubjectService()->addSubjectExtBindsBySubjectIdAndExtIds($subjectId, $extIds);
            }
        }
    }
}